package com.hulk.dryad.manage.framework.sequence.config;


import cn.ms.sequence.IdWorker;
import com.hulk.dryad.manage.framework.sequence.builder.DbSeqBuilder;
import com.hulk.dryad.manage.framework.sequence.builder.RedisSeqBuilder;
import com.hulk.dryad.manage.framework.sequence.range.impl.name.DateBizName;
import com.hulk.dryad.manage.framework.sequence.range.impl.name.DefaultBizName;
import com.hulk.dryad.manage.framework.sequence.sequence.Sequence;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;

import javax.sql.DataSource;


/**
 * @author hulk
 * @date 2019-05-26
 */
@Configuration
@ConditionalOnProperty(name = "enabled", prefix = BaseSequenceProperties.PREFIX, havingValue = "true")
public class SequenceAutoConfiguration {



	/**
	 * 数据库作为发号器的存储介质
	 */
	@Configuration
	@AutoConfigureAfter(DataSource.class)
	@ConditionalOnProperty(name = "name", prefix = BaseSequenceProperties.PREFIX, havingValue = "db")
	@EnableConfigurationProperties({SequenceDbProperties.class})
	public static class DbSequenceConfig {



		@Bean
		@ConditionalOnMissingBean
		public Sequence dbSequence(SequenceDbProperties  properties ,ObjectProvider<DataSource> dataSource) {
			return DbSeqBuilder
					.create()
					.bizName(new DefaultBizName(properties.getBizName()))
					.dataSource(dataSource.getIfAvailable())
					.step(properties.getStep())
					.stepStart(properties.getStepStart())
					.retryTimes(properties.getRetryTimes())
					.tableName(properties.getTableName())
					.build();
		}
	}


	/**
	 * Redis 作为发号器的存储介质
	 */
	@Configuration
	@AutoConfigureAfter(RedisAutoConfiguration.class)
	@ConditionalOnProperty(name = "name", prefix = BaseSequenceProperties.PREFIX, havingValue = "redis")
	@EnableConfigurationProperties({SequenceRedisProperties.class})
	public static class RedisSequenceConfig {



		@Bean(value = "seqRedisTemplate")
		@ConditionalOnMissingBean
		public StringRedisTemplate seqRedisTemplate(
				RedisConnectionFactory redisConnectionFactory) {
			return new StringRedisTemplate(redisConnectionFactory);
		}

		@Bean
		@ConditionalOnMissingBean
		public Sequence redisSequence(StringRedisTemplate seqRedisTemplate,SequenceRedisProperties  properties) {

			return RedisSeqBuilder
					.create()
					.bizName(new DateBizName(properties.getBizName()))
					.step(properties.getStep())
					.stepStart(properties.getStepStart()+ IdWorker.getId())
					.seqRedisTemplate(seqRedisTemplate)
					.build();
		}
	}


}